<?php

// MappingToCake v0.1 - Aplicaci�n la cual genera Vista y Controlador desde CakePHP para Flex
// Copyright (C) 2009  Blas Orlando Soto Mu�oz
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


class FlexMapping {
	
	//Creamos todos los controladores
	function createMediator($tables,$path,$cake_name) {
		foreach($tables as $table) {
			$file = fopen($path.'src/'.FlexMapping::deleteHyphen($table).'Mediator.as','w+') or message_error('Imposible abrir el archivo mediator');
			
			fwrite($file,"package
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	
	import mx.collections.XMLListCollection;
	import mx.controls.Alert;
	import mx.managers.PopUpManager;
	import mx.rpc.events.ResultEvent;
	import mx.events.ValidationResultEvent;
	
	import org.blas.rest4cake.RestService;
	
	public class ".FlexMapping::deleteHyphen($table)."Mediator
	{
		private var ".$table."Component:".FlexMapping::deleteHyphen($table)."Component;
		private var parent:DisplayObject;
		private var modelName:String = \"".$table."\";
		
		private var service:RestService = new RestService(ProyectName.name);
		
		private var listaXML:XMLListCollection = new XMLListCollection();
		
		public function ".FlexMapping::deleteHyphen($table)."Mediator(_parent:DisplayObject = null)
		{
			parent = _parent;
		}
		
		public function new".FlexMapping::deleteHyphen($table)."():void {
			".$table."Component = ".FlexMapping::deleteHyphen($table)."Component(PopUpManager.createPopUp(parent,".FlexMapping::deleteHyphen($table)."Component,true));
			".$table."Component.addEventListener(\"SAVE\",save);
			".$table."Component.addEventListener(\"SEARCH\",search);
			".$table."Component.addEventListener(\"DELETE\",del);
			".$table."Component.addEventListener(\"CLOSE\",close);
			PopUpManager.centerPopUp(".$table."Component);
		}
		
		public function save(event:Event):void {") or message_error("Write Error");
			FlexMapping::parametrosSave($file,$table);
			fwrite($file,"
		}

		public function search(event:Event):void {
			service.search(".$table."Component.ti_search.text, modelName, onSearch);
		}
		
		public function del(event:Event):void {
			".$table."Component.dataXML.@id = ".$table."Component.dg_lista.selectedItem.@id;
			service.del(".$table."Component.dataXML,modelName,onDelet);
		}
		
		public function onSearch(event:ResultEvent):void {
			var data:XML = event.result as XML;
			
			listaXML = new XMLListCollection(data.".rtrim($table,"s").");
			
			".$table."Component.listaXML = listaXML;
			".$table."Component.Clear();
			Alert.show(\"Busqueda Finalizada\",\"Busqueda\");
		}
		
		public function onSave(event:ResultEvent):void {
			var data:XML = event.result as XML;
			
			if (data.saved == 'true'){
				UpdateDg();
				".$table."Component.Clear();
				Alert.show(\"Datos Guardados Satisfactoriamente\",\"Guardado\");
			} 
			else {
				Alert.show(\"Imposible Guardar los Datos\",\"Error\");
			}
		}
		
		public function onDelet(event:ResultEvent):void {
			var data:XML = event.result as XML;
			
			if (data.deleted == 'true'){
				UpdateDg();
				".$table."Component.Clear();
				Alert.show(\"Datos Eliminados Satisfactoriamente\");
			} 
			else {
				Alert.show(\"Imposible eliminar los datos, pueden estar en uso \",\"Error\");
			}
		}
		
		public function close(event:Event):void {
			PopUpManager.removePopUp(".$table."Component);
		}
		
		private function UpdateDg():void {
			service.search(\"\", modelName, onUpdateDg);
		}
		
		private function onUpdateDg(event:ResultEvent):void {
			var data:XML = event.result as XML;
			
			listaXML = new XMLListCollection(data.".rtrim($table,"s").");
			
			".$table."Component.dg_lista.dataProvider = listaXML;
		}
	}
}
") or message_error("Write Error");
		}
		
		$file_pn = fopen($path.'src/ProyectName.as','w+') or message_error('Imposible abrir el archivo ProyectName.as');
		
		fwrite($file_pn,"package
{
	public class ProyectName
	{
		public static var name:String = \"".$cake_name."\";
	}
}") or message_error("Write Error");
	}
	
	private function parametrosSave($file,$table) {
		$atributos = array();
		$atributos_fk = array();
		$result = mysql_query("select * from ".$table);
		$bar = 0;
		
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$atributos[] = $column->name;
			}
			else if(strripos($column->name,"_id") !== false) {
				$atributos_fk_table[] = substr($column->name,0,strripos($column->name,"_"));
				$atributos_fk[] = $column->name;
				$bar++;
			}
		}
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\t\t\tvar validar".rtrim(FlexMapping::deleteHyphen($atributo),"s").":ValidationResultEvent = ".$table."Component.valida".rtrim(FlexMapping::deleteHyphen($atributo),"s").".validate();") or message_error("Write Error");
		}
		fwrite($file,"\n\n\t\t\tif(") or message_error("Write Error");
		$foo = true;
		foreach($atributos as $atributo) {
			if($foo) {
				fwrite($file,"validar".rtrim(FlexMapping::deleteHyphen($atributo),"s").".type == ValidationResultEvent.VALID") or message_error("Write Error");
				$foo = false;
			}
			else {
				fwrite($file," && validar".rtrim(FlexMapping::deleteHyphen($atributo),"s").".type == ValidationResultEvent.VALID") or message_error("Write Error");
			}
		}
		fwrite($file,") {") or message_error("Write Error");
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\t\t\t\t".$table."Component.dataXML.@".$atributo." = ".$table."Component.ti_".$atributo.".text;") or message_error("Write Error");
		}
		
		if($bar != 0){
			$bar = 0;
			foreach($atributos_fk as $atributo_fk) {
				fwrite($file,"\n\t\t\t\t".$table."Component.dataXML.@".$atributo_fk." = ".$table."Component.".$atributos_fk_table[$bar].".selectedItem.@id;") or message_error("Write Error");
				$bar++;
			}
		}
		
		fwrite($file,"\n\t\t\t\tservice.save(".$table."Component.dataXML, modelName, onSave);
			}") or message_error("Write Error");		
	}
	
	//Creamos todos las vistas en flex
	function createComponent($tables,$path,$cake_name) {
		foreach($tables as $table) {
			$file = fopen($path.'src/'.FlexMapping::deleteHyphen($table).'Component.mxml','w+') or message_error('Imposible abrir el archivo mediator');
			
			fwrite($file,'<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="600" height="500" title="'.FlexMapping::deleteHyphen($table).'" initialize="init()" >
	
	<mx:Script>
		<![CDATA[
			import mx.events.CloseEvent;
			import mx.controls.Alert;
			import org.blas.util.Selector;
			import org.blas.util.IdXMLComparator;
			import org.blas.rest4cake.RestService;
			import mx.rpc.events.ResultEvent;
			import mx.collections.XMLListCollection;
		
			private var comparator:IdXMLComparator = IdXMLComparator.getInstance();
			[Bindable]
			private var selector:Selector = new Selector(comparator);
			[Bindable]
			public var dataXML:XML = <'.rtrim($table,"s").' id="" />;
			[Bindable]
			public var listaXML:XMLListCollection = new XMLListCollection();
			
			') or message_error("Write Error");
			FlexMapping::generateXmlListCollection($file,$table,$cake_name);
			fwrite($file,'
			
			public function Clear():void {') or message_error("Write Error");
			FlexMapping::parametrosClear($file,$table);
			fwrite($file,'
			
				dg_lista.selectedIndex = -1;
				dataXML = <'.rtrim($table,"s").' id="" />;
			}
			
			public function Save():void {
				dispatchEvent(new Event("SAVE"));
			}
			
			private function doDelete():void {
				Alert.yesLabel = "Si";
				Alert.show("Esta seguro que desea eliminar este item?","Eliminar",3,this,Delete);
			}
			
			public function Delete(event:CloseEvent):void {
				if(event.detail == Alert.YES) {
					dispatchEvent(new Event("DELETE"));
				}
			}
			
			public function Search():void {
				dispatchEvent(new Event("SEARCH"));
			}
			
			public  function selectItem():void {
				dataXML = dg_lista.selectedItem as XML;') or message_error("Write Error");
			FlexMapping::selectComboItem($file,$table);
			fwrite($file,'
			}
			') or message_error("Write Error");
			FlexMapping::getFunctionCombo($file,$table);
			fwrite($file,'			
			public function close():void {
				dispatchEvent(new Event("CLOSE"));
			}') or message_error("Write Error");
			FlexMapping::labelFunction($file,$table);
			fwrite($file,'			
		]]>
	</mx:Script>
		
	<mx:Form id="formulario" top="10" bottom="10" left="10" right="10">
		<mx:HBox width="100%">
			<mx:TextInput width="100%" id="ti_search" enter="Search()"/>
			<mx:Button label="Buscar" id="bt_buscar" click="Search()"/>
		</mx:HBox>
		<mx:DataGrid width="100%" id="dg_lista" dataProvider="{listaXML}" change="selectItem()" height="100%">
			<mx:columns>') or message_error("Write Error");
			FlexMapping::parametrosDataGrid($file,$table);
			fwrite($file,'
			</mx:columns>
		</mx:DataGrid>') or message_error("Write Error");
			FlexMapping::parametrosFormItems($file,$table);
			fwrite($file,'
		<mx:HBox width="100%">
			<mx:Button label="Guardar" id="bt_guardar" click="Save()"/>
			<mx:Button label="Eliminar" id="bt_eliminar" click="doDelete()" enabled="{dg_lista.selectedItem}"/>
			<mx:Button label="Limpiar" id="bt_limpiar" click="Clear()"/>
			<mx:Button label="Cerrar" click="close()"/>
		</mx:HBox>
	</mx:Form>') or message_error("Write Error");
			FlexMapping::validators($file,$table);
			fwrite($file,'
</mx:Panel>') or message_error("Write Error");
		}
	}
	
	private function parametrosClear($file,$table) {
		$atributos = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$atributos[] = $column->name;
			}
		}
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\t\t\t\tti_".$atributo.".text = \"\";") or message_error("Write Error");
		}
		
	}
	
	private function parametrosSelectItem($file,$table) {
		$atributos = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$atributos[] = $column->name;
			}
		}
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\t\t\t\tti_".$atributo.".text = dataXML.@".$atributo.";") or message_error("Write Error");
		}
		
	}
	
	private function labelFunction($file,$table) {
		$atributos = array();
		$indices = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") !== false) {
				$atributos[] = substr($column->name,0,stripos($column->name,"_"));
			}
		}
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\n\t\t\tprivate function ".$atributo."Label(item:Object, column:DataGridColumn):String{
				return  item.".$atributo.".@nombre;
			}") or message_error("Write Error");
		}
	}
	
	private function selectComboItem($file,$table) {
		$atributos = array();
		$indices = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") !== false) {
				$atributos[] = substr($column->name,0,strripos($column->name,"_"));
			}
		}
		
		foreach($atributos as $atributo) {
			fwrite($file,"\n\t\t\t\tsetComboBoxItem(".$atributo.",dataXML.".$atributo.".@nombre);") or message_error("Write Error");
		}
	}
	
	private function getFunctionCombo($file,$table) {
		$atributos = array();
		$indices = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") !== false) {
				$atributos[] = substr($column->name,0,stripos($column->name,"_"));
			}
		}
		
		if(count($atributos) != 0) {
			fwrite($file,"\n\t\t\tprivate function setComboBoxItem(combo:ComboBox, name:String):void {
				var index:int = getComboBoxIndex(combo, name);
				if(index != -1) combo.selectedIndex = index;
			}
			
			private function getComboBoxIndex(combo:ComboBox, name:String):int{
					var index:int = -1;
					for(var i:int=0; i<combo.rowCount; i++) {
						combo.selectedIndex = i;
						var item:String = combo.selectedLabel;
						if(item == name) index = i;
					}
				return index;
			}") or message_error("Write Error");
		}
	}	
	
	private function parametrosDataGrid($file,$table) {
		$atributos = array();
		$indices = array();
		$result = mysql_query("select * from ".$table);
		$bar = 0;
		
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$atributos[] = $column->name;
				$bar++;
			}
			else if(strripos($column->name,"_id") !== false) {
				$atributos[] = substr($column->name,0,stripos($column->name,"_"));
				$indices[] = $bar;
				$bar++;
			}
		}
		
		$j = 0;
		foreach($atributos as $atributo) {
			if(in_array($j,$indices)) {
				fwrite($file,"\n\t\t\t\t<mx:DataGridColumn headerText=\"".rtrim(FlexMapping::deleteHyphen($atributo),"s")."\" labelFunction=\"".$atributo."Label\"/>") or message_error("Write Error");
			}
			else {
				fwrite($file,"\n\t\t\t\t<mx:DataGridColumn headerText=\"".rtrim(FlexMapping::deleteHyphen($atributo),"s")."\" dataField=\"@".$atributo."\"/>") or message_error("Write Error");
			}
			$j++;
		}
		
	}
	
	private function parametrosFormItems($file,$table) {
		$atributosFk = array();
		$items = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$items[] = $column->name;
			}
			else if(strripos($column->name,"_id") !== false) {
				$atributosFk[] = $column->name;
			}
		}
		
		if(count($items) > 0) {
			foreach($items as $item) {
				fwrite($file,"\n\t\t<mx:FormItem width=\"100%\" label=\"".rtrim(FlexMapping::deleteHyphen($item),"s")."\">
			<mx:TextInput id=\"ti_".$item."\" text=\"{dg_lista.selectedItem.@".$item."}\"/>
		</mx:FormItem>") or message_error("Write Error");
			}
		}
		
		if(count($atributosFk) > 0) {
			foreach($atributosFk as $atributoFk) {
				fwrite($file,"\n\t\t<mx:FormItem width=\"100%\" label=\"".rtrim(FlexMapping::deleteHyphen(rtrim($atributoFk,"_id")),"s")."\">
			<mx:ComboBox id=\"".rtrim($atributoFk,"_id")."\" dataProvider=\"{_".rtrim($atributoFk,"_id")."}\" labelField=\"@nombre\" selectedIndex=\"{selector.getSelectionIndex(_".rtrim($atributoFk,"_id").", dg_lista.selectedItem.".trim($atributoFk,"_id").")}\"></mx:ComboBox>
		</mx:FormItem>") or message_error("Write Error");
			}
		}
	}
	
	private function validators($file,$table) {
		$atributosFk = array();
		$items = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") === false && strcmp($column->name,"id") != 0) {
				$items[] = $column->name;
			}
		}
		
		if(count($items) > 0) {
			foreach($items as $item) {
				fwrite($file,"\n\t<mx:StringValidator id=\"valida".rtrim(FlexMapping::deleteHyphen($item),"s")."\" source=\"{ti_".$item."}\" property=\"text\" minLength=\"0\" maxLength=\"255\" tooLongError=\"Solo puede ingresar 255 caracteres maximos\" requiredFieldError=\"Complete ".rtrim(FlexMapping::deleteHyphen($item),"s")."\"/>") or message_error("Write Error");
			}
		}
	}
	
	private function generateXmlListCollection($file,$table,$cake_name) {
		$atributosXML = array();
		$result = mysql_query("select * from ".$table);
		for($i = 0; $i < mysql_num_fields($result); $i++) {
			$column = mysql_fetch_field($result,$i);
			if(strripos($column->name,"_id") !== false) {
				$atributosXML[] = $column->name;
			}
		}
		
		if(count($atributosXML) != 0) {
			foreach($atributosXML as $atributoXML) {
				fwrite($file,"\n\t\t\t[Bindable]\n\t\t\tpublic var _".rtrim($atributoXML,"_id").":XMLListCollection;") or message_error("Write Error");	
			}
			fwrite($file,"\n\n");
		}
		
		fwrite($file,"\n\n\t\t\tprivate function init():void {");
		
		if(count($atributosXML) != 0) {
			fwrite($file,"\n\t\t\t\tvar service:RestService = new RestService(ProyectName.name);\n");
			foreach($atributosXML as $atributoXML) {
				fwrite($file,"\n\t\t\t\tservice.retrieve(\"".rtrim($atributoXML,"_id")."s\", fill".FlexMapping::deleteHyphen(rtrim($atributoXML,"_id")).");");
			}
		}
		
		fwrite($file,"\n\n\t\t\t}");
		
		if(count($atributosXML) != 0) {
			foreach($atributosXML as $atributoXML) {
				fwrite($file,"\n\n\t\t\tprivate function fill".FlexMapping::deleteHyphen(rtrim($atributoXML,"_id"))."(event:ResultEvent):void{
				_".rtrim($atributoXML,"_id")." = new XMLListCollection(XML(event.result).".rtrim($atributoXML,"_id").");
			}");
			}
		}
	}
	
	//Eliminamos los guiones bajos de las tablas
	private function deleteHyphen($table) { // Tambien agrega mayuscula al principio
		if(stripos($table,"_") === false ) {
			return ucfirst($table); // no se encontraron guiones bajos y solo restornamos la taba en mayuscula
		} else {
			$table = ucfirst($table); // colocamos la tabla en mayuscula
			$posHyphen = stripos($table,"_"); // guardamos la posicion de el guion bajo
			$firstPartTable = substr($table,0,$posHyphen); // retornamos el nombre de la tabla sin el guion bajo
			$secondPartTable = ucfirst(substr($table,$posHyphen+1,strlen($table))); // guardamos la segunda parte de la tabla en mayuscula
			return $firstPartTable.$secondPartTable; // retornamos el nombre de la tabla en orden
		}
	}
}
?>
